<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:fn="http://www.w3.org/2005/xpath-functions"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:data="data">
	
	<xsl:output method="text" encoding="UTF-8" indent="no"/>
	
	<xsl:param name="package"/>
	
	<xsl:template match="/entities">
/*
 *	Generated file, do not modify.
 */
package <xsl:value-of select="$package"/>;

import java.util.Map;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.DatastoreFailureException;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.datastore.Link;
import com.google.appengine.api.datastore.Email;

import net.cloudcodex.server.Context;
import <xsl:value-of select="$package"/>.Data.*;

/**
 *	DAO generated class to manipulate {@link Data} classes.
 */
public class DAO {

	/**
	 *	Wrapped store.
	 */
	protected final DatastoreService store;

	/**
	 *	@param store wrapped store.
	 */	
	public DAO(DatastoreService store) {
		this.store = store;
	}
	
	/**
	 *	Return the wrapped store.
	 */
	public DatastoreService getStore() {
		return store;
	}
	
	/**
	 *	Save data if modified.
	 */
	public void save(Context context, Data... datas) {
		if(datas != null) {
			for(Data data : datas) {
				if(data != null &amp;&amp; data.modified()) {
					data.ensureNotNull();
					store.put(data.getEntity());
					data.unmodify();
					if(context != null) {
						context.cache(data);
					}
				}
			}		
		}
	}

	/**
	 *	Save a data if modified.
	 */
	public void save(Context context, Transaction txn, Data... datas) {
		if(datas != null) {
			for(Data data : datas) {
				if(data != null &amp;&amp; data.modified()) {
					data.ensureNotNull();
					store.put(txn, data.getEntity());
					data.unmodify();
					if(context != null) {
						// we're not sure the tx will be validated so force reload
						context.uncache(data);
					}
				}
			}		
		}
	}

	/**
	 * Starts a new transaction.
	 * @return the new transaction.
	 * @see DatastoreService#beginTransaction()
	 */
	public Transaction beginTransaction() {
		return store.beginTransaction();
	}

	/**
	 *	Removes a list of Data from another list of Data.
	 */
	public void removeAll(List&lt;? extends Data&gt; from, List&lt;? extends Data&gt; what) {
		if(from == null || what == null) {
			return;
		}
		
		final Iterator&lt;? extends Data&gt; ifrom = from.iterator();
		from:while(ifrom.hasNext()) {
			final Data itemfrom = ifrom.next();
			final Iterator&lt;? extends Data&gt; iwhat = what.iterator();
			while(iwhat.hasNext()) {
				if(itemfrom.getKey().equals(iwhat.next().getKey())) {
					ifrom.remove();
					continue from;
				}
			}
		}
	}

	/**
	 *	Delete a data and all its children.
	 */
	public void delete(Context context, Data data) throws DatastoreFailureException {
		if(data != null) {
			final Query query = new Query(data.getKey());
			query.setKeysOnly();
			final List&lt;Key&gt; keys = toKeys(store.prepare(query).asList(FetchOptions.Builder.withDefaults()));
			
			if(keys != null &amp;&amp; !keys.isEmpty()) {
				store.delete(keys);
				if(context != null) {
					context.uncache(keys);
				}
			}	
			store.delete(data.getKey());
			if(context != null) {
				context.uncache(data);
			}
		}
	}
	
	/**
	 *	Delete a data and all its children.
	 */
	public void delete(Context context, Transaction txn, Data data) throws DatastoreFailureException {
		if(data != null) {
			final Query query = new Query(data.getKey());
			query.setKeysOnly();
			final List&lt;Key&gt; keys = toKeys(store.prepare(query).asList(FetchOptions.Builder.withDefaults()));
			
			if(keys != null &amp;&amp; !keys.isEmpty()) {
				store.delete(txn, keys);
				if(context != null) {
					context.uncache(keys);
				}
			}	
			store.delete(txn, data.getKey());
			if(context != null) {
				context.uncache(data);
			}
		}
	}
	
	/**
	 *	Utility method to get a List&amp;lt;Key&amp;gt; from a List&amp;lt;Entity&amp;gt;.
	 */
	public List&lt;Key&gt; toKeys(Collection&lt;Entity&gt; entities) {
		if(entities == null) {
			return null;
		}
		final List&lt;Key&gt; keys = new ArrayList&lt;Key&gt;(entities.size());
		for(Entity entity : entities) {
			keys.add(entity.getKey());
		}
		return keys;
	}

	/**
	 *	Utility method to get a List&amp;lt;Key&amp;gt; from a List&amp;lt;Data&amp;gt;.
	 */
	public List&lt;Key&gt; toKeysFromData(Collection&lt;? extends Data&gt; entities) {
		if(entities == null) {
			return null;
		}
		final List&lt;Key&gt; keys = new ArrayList&lt;Key&gt;(entities.size());
		for(Data entity : entities) {
			keys.add(entity.getKey());
		}
		return keys;	
	}
	
	/**
	 *	Utility method to read a List of Data. May return multiple types
	 *	of Data.
	 */
	@SuppressWarnings("unchecked")
	public &lt;T extends Data&gt; List&lt;T&gt; read(Context context, Class&lt;T&gt; clazz, Collection&lt;Key&gt; keys) {
		
		if(keys == null || keys.isEmpty()) {
			return null;
		}
		
		try {
			final Map&lt;Key, Entity&gt; map = store.get(keys);
			final List&lt;T&gt; datas = new ArrayList&lt;T&gt;(map.size());
			for(Entity entity : map.values()) {
				final Data data = wrap(context, entity);
				if(data != null &amp;&amp; clazz.isAssignableFrom(data.getClass())) {
					datas.add((T) data);
				}
			}
			return datas;
		} catch (DatastoreFailureException e) {
			return null;
		}
	}
	
	/**
	 *	Wrap an entity, depending on its kind.
	 *	@return null for unknown kinds, the wrapping Data object else.
	 */
	public Data wrap(Context context, Entity entity) {
	<xsl:for-each select="//entity">
		if("<xsl:value-of select="@name"/>".equals(entity.getKey().getKind())) {
			<xsl:choose>
				<xsl:when test="count(entity[@parent-property]) > 0">
			final Data data = fetch<xsl:value-of select="@name"/>(context, new Data.<xsl:value-of select="@name"/>(entity));
				</xsl:when>
				<xsl:otherwise>
			final Data data = new Data.<xsl:value-of select="@name"/>(entity);
				</xsl:otherwise>
			</xsl:choose>
			if(context != null) {
				context.cache(data);
			}
			return data;
		}
	</xsl:for-each>
		return null;
	}

		<xsl:apply-templates select="entity">
			<xsl:with-param name="P">Data</xsl:with-param>
		</xsl:apply-templates>	

}
	
	</xsl:template>	

	<!-- Types shortcuts translation -->
	<xsl:function name="data:type" as="xs:string?">
		<xsl:param name="type" as="xs:string?"/>
		<xsl:choose>
			<xsl:when test="ends-with($type, '[]')"><xsl:value-of select="concat('List&lt;', data:type(substring($type, 1, string-length($type) - 2)), '&gt;')"/></xsl:when>
			<xsl:when test="$type = 'string'">String</xsl:when>
			<xsl:when test="$type = 'object'">Object</xsl:when>
			<xsl:when test="$type = 'long'">Long</xsl:when>
			<xsl:when test="$type = 'long'">Integer</xsl:when>
			<xsl:when test="$type = 'short'">Short</xsl:when>
			<xsl:when test="$type = 'float'">Float</xsl:when>
			<xsl:when test="$type = 'double'">Double</xsl:when>
			<xsl:when test="$type = 'blob'">com.google.appengine.api.datastore.Blob</xsl:when>
			<xsl:when test="$type = 'bytes'">com.google.appengine.api.datastore.ShortBlob</xsl:when>
			<xsl:when test="$type = 'category'">com.google.appengine.api.datastore.Category</xsl:when>
			<xsl:when test="$type = 'key' or starts-with($type, 'key:')">Key</xsl:when>
			<xsl:when test="$type = 'boolean'">Boolean</xsl:when>
			<xsl:when test="$type = 'date'">java.util.Date</xsl:when>
			<xsl:when test="$type = 'text'">String</xsl:when>
			<xsl:when test="$type = 'email'">String</xsl:when>
			<xsl:when test="$type = 'url'">String</xsl:when>
			<xsl:otherwise><xsl:value-of select="$type"/></xsl:otherwise>
		</xsl:choose>
	</xsl:function>
	
	<!-- Types shortcuts translation -->
	<xsl:function name="data:type2" as="xs:string?">
		<xsl:param name="type" as="xs:string?"/>
		<xsl:choose>
			<xsl:when test="ends-with($type, '[]')"><xsl:value-of select="data:type(substring($type, 1, string-length($type) - 2))"/></xsl:when>
			<xsl:otherwise><xsl:value-of select="data:type($type)"/></xsl:otherwise>
		</xsl:choose>
	</xsl:function>	

	<xsl:function name="data:capitalize" as="xs:string?" >
		<xsl:param name="arg" as="xs:string?"/> 
		<xsl:sequence select="concat(upper-case(substring($arg,1,1)), substring($arg,2))"/>
	</xsl:function>

	<xsl:template match="entity">
		<xsl:param name="P" />

	<xsl:choose>
		<xsl:when test="parent::entity">
	
	/**
	 * @param id long id of the entity.
	 * @param context data cache.
	 * @param parentKey <xsl:value-of select="parent::entity/@name"/>'s key.
	 * @return the <xsl:value-of select="@name"/>.
	 */
	public Data.<xsl:value-of select="@name"/> read<xsl:value-of select="@name"/>(Context context, Key parentKey, long id) {
		return read<xsl:value-of select="@name"/>(context, Data.<xsl:value-of select="@name"/>.createKey(parentKey, id));
	}

	/**
	 * @param parentKey <xsl:value-of select="parent::entity/@name"/>'s key.
	 * @param id String id of the entity.
	 * @param context data cache.
	 * @return the <xsl:value-of select="@name"/>.
	 */
	public Data.<xsl:value-of select="@name"/> read<xsl:value-of select="@name"/>(Context context, Key parentKey, String id) {
		return read<xsl:value-of select="@name"/>(context, Data.<xsl:value-of select="@name"/>.createKey(parentKey, id));
	}
		</xsl:when>
		<xsl:otherwise>
	/**
	 * @param id long id of the entity.
	 * @param context data cache.
	 * @return the <xsl:value-of select="@name"/>.
	 */
	public Data.<xsl:value-of select="@name"/> read<xsl:value-of select="@name"/>(Context context, long id) {
		return read<xsl:value-of select="@name"/>(context, Data.<xsl:value-of select="@name"/>.createKey(id));
	}

	/**
	 * @param id String id of the entity.
	 * @param context data cache.
	 * @return the <xsl:value-of select="@name"/>.
	 */
	public Data.<xsl:value-of select="@name"/> read<xsl:value-of select="@name"/>(Context context, String id) {
		return read<xsl:value-of select="@name"/>(context, Data.<xsl:value-of select="@name"/>.createKey(id));
	}
		</xsl:otherwise>
	</xsl:choose>

	/**
	 * @param key of the entity.
	 * @return the <xsl:value-of select="@name"/>.
	 */	
	private Data.<xsl:value-of select="@name"/> read<xsl:value-of select="@name"/>(Key key) {

		if(key == null) {
			return null;
		}
	
		try {
			<xsl:choose>
				<xsl:when test="count(entity[@parent-property]) > 0">
					return fetch<xsl:value-of select="@name"/>(context, new Data.<xsl:value-of select="@name"/>(store.get(key)));
				</xsl:when>
				<xsl:otherwise>
					return new Data.<xsl:value-of select="@name"/>(store.get(key));
				</xsl:otherwise>
			</xsl:choose>	
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
	
	/**
	 * Idem as {@link #read<xsl:value-of select="@name"/>(Key key)} but uses an object cache.
	 */
	public Data.<xsl:value-of select="@name"/> read<xsl:value-of select="@name"/>(Context context, Key key) {

		if(key == null) {
			return null;
		}

		Data.<xsl:value-of select="@name"/> data = null;
		if(context != null) {
			data = (Data.<xsl:value-of select="@name"/>) context.getData(key);
		}
		if(data == null) {
			data = read<xsl:value-of select="@name"/>(key);
			if(context != null &amp;&amp; data != null) {
				context.cache(data);
			}
		}
		return data;
	}
	
	/**
	 *	Utility method to read a list of {@link Data.<xsl:value-of select="@name"/>} from the keys list.
	 */	
	public List&lt;Data.<xsl:value-of select="@name"/>&gt; read<xsl:value-of select="@name"/>s(Context context, Collection&lt;Key&gt; keys) {

		if(keys == null || keys.isEmpty()) {
			return null;
		}
		
		try {
			final Map&lt;Key, Entity&gt; map = store.get(keys);
			return to<xsl:value-of select="@name"/>s(context, map.values());
		} catch (DatastoreFailureException e) {
			return null;
		}
	}
	
	
	<xsl:if test="count(entity[@parent-property]) > 0">
	/**
	 *	Fetch all data properties based on children.
	 */
	public <xsl:value-of select="@name"/> fetch<xsl:value-of select="@name"/>(Context context, <xsl:value-of select="@name"/> data) {
		<xsl:for-each select="entity[@parent-property]">
		data.set<xsl:value-of select="data:capitalize(@parent-property)"/>(fetch<xsl:value-of select="parent::entity/@name"/><xsl:value-of select="@name"/>s(context, data.getKey(), null));
		</xsl:for-each>
		return data;
	}
	</xsl:if>

	<xsl:if test="@timestamp or count(entity[@parent-property]) > 0">
	/**
	 *	Save {@link Data.<xsl:value-of select="@name"/>}s if modified.
	 */
	public void save(Context context, Data.<xsl:value-of select="@name"/>... datas) {
		if(datas != null) {
			<xsl:if test="@timestamp">
			final java.util.Date date = new java.util.Date();
			for(Data.<xsl:value-of select="@name"/> data : datas) {
				data.getEntity().setProperty("<xsl:value-of select="@timestamp"/>", date);
			}
			</xsl:if>
			save(context, (Data[]) datas);
			
			<xsl:if test="count(entity[@parent-property]) > 0">
				for(Data.<xsl:value-of select="@name"/> data : datas) {
					<xsl:for-each select="entity[@parent-property]">
					final List&lt;<xsl:value-of select="@name"/>&gt; <xsl:value-of select="@parent-property"/> = data.get<xsl:value-of select="data:capitalize(@parent-property)"/>();
			
					// Search all rows to delete.
					final List&lt;Key&gt; <xsl:value-of select="@parent-property"/>Keys = fetch<xsl:value-of select="parent::entity/@name"/><xsl:value-of select="@name"/>sKeys(context, data.getKey());
					if(<xsl:value-of select="@parent-property"/>Keys != null) {
						keys: for(Key key : <xsl:value-of select="@parent-property"/>Keys) {
							if(<xsl:value-of select="@parent-property"/> != null) {
								for(<xsl:value-of select="@name"/> item : <xsl:value-of select="@parent-property"/>) {
									if(key.equals(item.getKey())) {
										// row is new or modified
										continue keys;
									}
								}
							}
							// row is no more linked to data.
							store.delete(key);
						}
					}
							
					if(<xsl:value-of select="@parent-property"/> != null) {
						// save the others rows
						for(<xsl:value-of select="@name"/> item : <xsl:value-of select="@parent-property"/>) {
							save(context, item);
						}
					}
					</xsl:for-each>
				}
			</xsl:if>
		}
	}
	
	
	/**
	 *	Save {@link Data.<xsl:value-of select="@name"/>}s if modified.
	 */
	public void save(Context context, Transaction txn, Data.<xsl:value-of select="@name"/>... datas) {
		if(datas != null) {
			<xsl:if test="@timestamp">
			final java.util.Date date = new java.util.Date();
			for(Data.<xsl:value-of select="@name"/> data : datas) {
				data.getEntity().setProperty("<xsl:value-of select="@timestamp"/>", date);
			}
			</xsl:if>
			save(context, txn, (Data[]) datas);
			
			<xsl:if test="count(entity[@parent-property]) > 0">
				for(Data.<xsl:value-of select="@name"/> data : datas) {
					<xsl:for-each select="entity[@parent-property]">
					final List&lt;<xsl:value-of select="@name"/>&gt; <xsl:value-of select="@parent-property"/> = data.get<xsl:value-of select="data:capitalize(@parent-property)"/>();
			
					// Search all rows to delete.
					final List&lt;Key&gt; <xsl:value-of select="@parent-property"/>Keys = fetch<xsl:value-of select="parent::entity/@name"/><xsl:value-of select="@name"/>sKeys(context, data.getKey());
					if(<xsl:value-of select="@parent-property"/>Keys != null) {
						keys: for(Key key : <xsl:value-of select="@parent-property"/>Keys) {
							if(<xsl:value-of select="@parent-property"/> != null) {
								for(<xsl:value-of select="@name"/> item : <xsl:value-of select="@parent-property"/>) {
									if(key.equals(item.getKey())) {
										// row is new or modified
										continue keys;
									}
								}
							}
							// row is no more linked to data.
							store.delete(txn, key);
						}
					}
							
					if(<xsl:value-of select="@parent-property"/> != null) {
						// save the others rows
						for(<xsl:value-of select="@name"/> item : <xsl:value-of select="@parent-property"/>) {
							save(context, txn, item);
						}
					}
					</xsl:for-each>
				}
			</xsl:if>
		}
	}
	
	</xsl:if>
	
	
	<xsl:if test="parent::entity/@name">

	/**
	 * Fetch the {@link Data.<xsl:value-of select="@name"/>}s id of a {@link Data.<xsl:value-of select="parent::entity/@name"/>}.
	 * @param ancestorKey key of the <xsl:value-of select="parent::entity/@name"/>.
	 * @return the <xsl:value-of select="@name"/>s keys of a <xsl:value-of select="parent::entity/@name"/>.
	 */	
	public List&lt;Key&gt; fetch<xsl:value-of select="parent::entity/@name"/><xsl:value-of select="@name"/>sKeys(Key ancestorKey, Data.<xsl:value-of select="@name"/>.Properties... sort) {

		final Query query = sort(new Query(Data.<xsl:value-of select="@name"/>.__KIND, ancestorKey), sort);
		query.setKeysOnly();
		return toKeys(store.prepare(query).asList(FetchOptions.Builder.withDefaults()));
	}

	/**
	 * Fetch the {@link Data.<xsl:value-of select="@name"/>}s of a {@link Data.<xsl:value-of select="parent::entity/@name"/>}.
	 * @param ancestorKey key of the <xsl:value-of select="parent::entity/@name"/>.
	 * @param fetch datastore fetch options.
	 * @return the <xsl:value-of select="@name"/>s of a <xsl:value-of select="parent::entity/@name"/>.
	 */	
	public List&lt;Data.<xsl:value-of select="@name"/>&gt; fetch<xsl:value-of select="parent::entity/@name"/><xsl:value-of select="@name"/>s(Context context, Key ancestorKey, FetchOptions fetch, Data.<xsl:value-of select="@name"/>.Properties... sort) {
		final Query query = sort(new Query(Data.<xsl:value-of select="@name"/>.__KIND, ancestorKey), sort);
		return to<xsl:value-of select="@name"/>s(context, store.prepare(query).asList(fetch != null ? fetch : FetchOptions.Builder.withDefaults()));
	}

	/**
	 * Fetch the {@link Data.<xsl:value-of select="@name"/>}s of a {@link Data.<xsl:value-of select="parent::entity/@name"/>}.
	 * @param ancestor the <xsl:value-of select="parent::entity/@name"/>.
	 * @param fetch datastore fetch options.
	 * @return the <xsl:value-of select="@name"/>s of a <xsl:value-of select="parent::entity/@name"/>.
	 */	
	public List&lt;Data.<xsl:value-of select="@name"/>&gt; fetch<xsl:value-of select="parent::entity/@name"/><xsl:value-of select="@name"/>s(Context context, Data.<xsl:value-of select="parent::entity/@name"/> ancestor, FetchOptions fetch, Data.<xsl:value-of select="@name"/>.Properties... sort) {
		return ancestor == null ? null : fetch<xsl:value-of select="parent::entity/@name"/><xsl:value-of select="@name"/>s(context, ancestor.getKey(), fetch, sort);
	}
	
	</xsl:if>
	
	public List&lt;Data.<xsl:value-of select="@name"/>&gt; asListOf<xsl:value-of select="@name"/>s(Context context, Query query, FetchOptions fetch, Data.<xsl:value-of select="@name"/>.Properties... sort) {
		sort(query, sort);
		return to<xsl:value-of select="@name"/>s(context, store.prepare(query).asList(fetch != null ? fetch : FetchOptions.Builder.withDefaults()));
	}

	public Data.<xsl:value-of select="@name"/> asSingle<xsl:value-of select="@name"/>(Context context, Query query) {
		final Entity entity = store.prepare(query).asSingleEntity();
		final Data.<xsl:value-of select="@name"/> data = entity == null ? null : new Data.<xsl:value-of select="@name"/>(entity);
		if(data != null &amp;&amp; context != null) {
			context.cache(data);
		}
		return data;
	}

	
	<xsl:for-each select="property[@indexed = 'true']">
		<xsl:variable name="name" select="data:capitalize(@name)"/>
		<xsl:variable name="entity" select="parent::entity/@name"/>
		<xsl:variable name="type" select="data:type2(@type)"/>
		
	/**
	 *	Utility method, prepare a filtered query on property "<xsl:value-of select="@name"/>" for {@link Data.<xsl:value-of select="$entity"/>}
	 */
	public Query add<xsl:value-of select="$entity"/>FilterOn<xsl:value-of select="$name"/>(Query query, FilterOperator operator, <xsl:value-of select="$type"/> value) {
		<xsl:choose>
			<xsl:when test="@type = 'text'">
		return query.addFilter("<xsl:value-of select="@name"/>", operator, value == null ? null : new Text(value));
			</xsl:when>
			<xsl:when test="@type = 'url'">
		return query.addFilter("<xsl:value-of select="@name"/>", operator, value == null ? null : new Link(value));
			</xsl:when>
			<xsl:when test="@type = 'email'">
		return query.addFilter("<xsl:value-of select="@name"/>", operator, value == null ? null : new Email(value));
			</xsl:when>
			<xsl:otherwise>
		return query.addFilter("<xsl:value-of select="@name"/>", operator, value);
			</xsl:otherwise>
		</xsl:choose>
	}

	/**
	 *	Utility method to search {@link Data.<xsl:value-of select="$entity"/>} with a filter on "<xsl:value-of select="@name"/>" property.
	 */
	public List&lt;Data.<xsl:value-of select="$entity"/>&gt; filter<xsl:value-of select="$entity"/>sOn<xsl:value-of select="$name"/>(Context context, FetchOptions fetch, FilterOperator operator, <xsl:value-of select="$type"/> value, Data.<xsl:value-of select="$entity"/>.Properties... sort) {
		final Query query = sort(add<xsl:value-of select="$entity"/>FilterOn<xsl:value-of select="$name"/>(query<xsl:value-of select="$entity"/>(), operator, value), sort);
		return to<xsl:value-of select="$entity"/>s(context, store.prepare(query).asList(fetch != null ? fetch : FetchOptions.Builder.withDefaults()));
	}

	</xsl:for-each>
	
	<xsl:if test="@timestamp">
		<xsl:variable name="Timestamp" select="data:capitalize(@timestamp)"/>

	/**
	 *	Utility method, prepare a filtered query on property "<xsl:value-of select="@timestamp"/>" for {@link Data.<xsl:value-of select="@name"/>}
	 */
	public Query add<xsl:value-of select="@name"/>FilterOn<xsl:value-of select="$Timestamp"/>(Query query, FilterOperator operator, java.util.Date value) {
		return query.addFilter("<xsl:value-of select="@timestamp"/>", operator, value);
	}

	/**
	 *	Utility method to search {@link Data.<xsl:value-of select="@name"/>} with a filter on "<xsl:value-of select="@timestamp"/>" property.
	 */
	public List&lt;Data.<xsl:value-of select="@name"/>&gt; filter<xsl:value-of select="@name"/>sOn<xsl:value-of select="$Timestamp"/>(Context context, FetchOptions fetch, FilterOperator operator, java.util.Date value, Data.<xsl:value-of select="@name"/>.Properties... sort) {
		final Query query = sort(add<xsl:value-of select="@name"/>FilterOn<xsl:value-of select="$Timestamp"/>(query<xsl:value-of select="@name"/>(), operator, value), sort);
		return to<xsl:value-of select="@name"/>s(context, store.prepare(query).asList(fetch != null ? fetch : FetchOptions.Builder.withDefaults()));
	}
	
	</xsl:if>
	
	/**
	 *	Utility method to add sort (ascending) on a query for {@link Data.<xsl:value-of select="@name"/>}.
	 *  @param query query which to add sort command
	 *  @param sort all properties to use for sort, they must be indexed.
	 */
	public Query sort(Query query, Data.<xsl:value-of select="@name"/>.Properties... sort) {
		if(sort != null) {
			for(Data.<xsl:value-of select="@name"/>.Properties property : sort) {
				if(!property.isIndexed()) {
					throw new RuntimeException("Property '" + property.getFullName() + "' is not indexed");
				}
				query.addSort(property.getName());
			}
		}
		return query;
	}
	
	/**
	 *	Utility method to translate a List&lt;Entity&gt; to List&lt;Data.<xsl:value-of select="@name"/>&gt;.
	 *  Note : fetch data !
	 */
	public List&lt;Data.<xsl:value-of select="@name"/>&gt; to<xsl:value-of select="@name"/>s(Context context, Collection&lt;Entity&gt; entities) {
		if(entities == null || entities.isEmpty()) {
			return null;
		}
		final List&lt;Data.<xsl:value-of select="@name"/>&gt; datas = new ArrayList&lt;Data.<xsl:value-of select="@name"/>&gt;();
		for(Entity entity : entities) {
			<xsl:choose>
				<xsl:when test="count(entity[@parent-property]) > 0">
			final Data.<xsl:value-of select="@name"/> data = fetch<xsl:value-of select="@name"/>(new Data.<xsl:value-of select="@name"/>(entity));
				</xsl:when>
				<xsl:otherwise>
			final Data.<xsl:value-of select="@name"/> data = new Data.<xsl:value-of select="@name"/>(entity);
				</xsl:otherwise>
			</xsl:choose>
			if(context != null) {
				context.cache(data);
			}
			datas.add(data);
		}
		return datas;
	}


	/**
	 *	Utility method, just create a query for {@link Data.<xsl:value-of select="@name"/>}.
	 */
	public Query query<xsl:value-of select="@name"/>() {
		return new Query(Data.<xsl:value-of select="@name"/>.__KIND);
	}

	/**
	 *	Utility method, just create a query for {@link Data.<xsl:value-of select="@name"/>}.
	 *	@param parentKey the parent key.
	 */
	public Query query<xsl:value-of select="@name"/>(Key parentKey) {
		return new Query(Data.<xsl:value-of select="@name"/>.__KIND, parentKey);
	}


		<xsl:apply-templates select="entity">
			<xsl:with-param name="P"><xsl:value-of select="@name"/></xsl:with-param>
		</xsl:apply-templates>	
	</xsl:template>
		
</xsl:stylesheet>